package com.ruoyi.business.service.impl;

import com.ruoyi.business.constant.IBusinessConstant;
import com.ruoyi.business.domain.ExtModelDef;
import com.ruoyi.business.domain.ExtModelField;
import com.ruoyi.business.domain.ExtModelFieldRef;
import com.ruoyi.business.mapper.ExtModelDefInstanceMapper;
import com.ruoyi.business.mapper.ExtModelFieldRefMapper;
import com.ruoyi.business.service.IDataSourceService;
import com.ruoyi.business.service.IExtModelFieldRefService;
import com.ruoyi.business.service.IExtModelFieldService;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.security.utils.SecurityUtils;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 模型字段引用Service业务层处理
 *
 * @author ruoyi
 * @date 2024-01-08
 */
@Service
public class ExtModelFieldRefServiceImpl implements IExtModelFieldRefService
{
    @Autowired
    private ExtModelFieldRefMapper extModelFieldRefMapper;
    @Autowired
    private IExtModelFieldService extModelFieldService;
    @Autowired
    private IDataSourceService dataSourceService;
    @Autowired
    private ExtModelDefInstanceMapper extModelDefInstanceMapper;
    /**
     * 查询模型字段引用
     *
     * @param id 模型字段引用主键
     * @return 模型字段引用
     */
    @Override
    public ExtModelFieldRef selectExtModelFieldRefById(Long id)
    {
        return extModelFieldRefMapper.selectExtModelFieldRefById(id);
    }

    /**
     * 查询模型字段引用列表
     *
     * @param extModelFieldRef 模型字段引用
     * @return 模型字段引用
     */
    @Override
    public List<ExtModelFieldRef> selectExtModelFieldRefList(ExtModelFieldRef extModelFieldRef)
    {
        return extModelFieldRefMapper.selectExtModelFieldRefList(extModelFieldRef);
    }

    /**
     * 新增模型字段引用
     *
     * @param extModelFieldRef 模型字段引用
     * @return 结果
     */
    @Override
    public int insertExtModelFieldRef(ExtModelFieldRef extModelFieldRef)
    {
        ExtModelField extModelField = checkInsert(extModelFieldRef);

        extModelFieldRef.setCreateTime(DateUtils.getNowDate());
        extModelFieldRef.setCreateBy(SecurityUtils.getUsername());
        int row =  extModelFieldRefMapper.insertExtModelFieldRef(extModelFieldRef);
        //检查信息范围必须为全局
        if(!IBusinessConstant.SCOPE_GLOBAL.equals(extModelField.getScope()))
            throw new ServiceException("引用字段必须为全局的！");

        String dbType = extModelFieldService.getDbType(extModelField.getFieldWidth(),extModelField.getScheme());
        //切换数据源
        SqlSession sqlSession = null;
        try {
            String key = dataSourceService.getKey(SecurityUtils.getEnterpriseCode(),SecurityUtils.getApplicationCode(),extModelFieldRef.getDatasourceName());
            sqlSession = dataSourceService.switchDataSource(key);
            //修改原表，增加字段
            extModelField.setEnName(extModelFieldRef.getEnName());
            extModelField.setFieldType(dbType);
            extModelDefInstanceMapper = sqlSession.getMapper(ExtModelDefInstanceMapper.class);
            extModelDefInstanceMapper.addField(extModelField);
        }finally {
            if(sqlSession!=null){
                sqlSession.close();
            }
        }
        return row;
    }

    /**
     * 检查插入数据
     * @param extModelFieldRef
     * @return
     */
    private ExtModelField checkInsert(ExtModelFieldRef extModelFieldRef) {
        ExtModelField extModelField = extModelFieldService.selectExtModelFieldById(extModelFieldRef.getExtModelFieldId());
        if(extModelField== null)
            throw new ServiceException("无效引用字段!");
        //检查字段英文，字段中文名是否重复
        Map<String,Object> searchMap = new HashMap<>();
        //私有范围，同一个数据源，同一个英文表名不能重复(关联字段定义表查询)
        searchMap.put("datasourceName", extModelFieldRef.getDatasourceName());
        searchMap.put("enName", extModelFieldRef.getEnName());
        searchMap.put("fieldEnName", extModelField.getFieldEnName());
        if(extModelFieldRefMapper.selectCountAssociation(searchMap)>0)
            throw new ServiceException("字段名:"+ extModelField.getFieldEnName()+"已经存在!");
        searchMap.put("fieldCnName", extModelField.getFieldCnName());
        searchMap.remove("fieldEnName");
        if(extModelFieldRefMapper.selectCountAssociation(searchMap)>0)
            throw new ServiceException("字段名:"+ extModelField.getFieldCnName()+"已经存在!");
        return extModelField;
    }

    /**
     * 修改模型字段引用
     *
     * @param extModelFieldRef 模型字段引用
     * @return 结果
     */
    @Override
    public int updateExtModelFieldRef(ExtModelFieldRef extModelFieldRef)
    {
        extModelFieldRef.setUpdateTime(DateUtils.getNowDate());
        int row =  extModelFieldRefMapper.updateExtModelFieldRef(extModelFieldRef);
        return row;
    }

    /**
     * 批量删除模型字段引用
     *
     * @param ids 需要删除的模型字段引用主键
     * @return 结果
     */
    @Override
    public int deleteExtModelFieldRefByIds(Long[] ids)
    {
        return extModelFieldRefMapper.deleteExtModelFieldRefByIds(ids);
    }

    /**
     * 删除模型字段引用信息
     *
     * @param id 模型字段引用主键
     * @return 结果
     */
    @Override
    public int deleteExtModelFieldRefById(Long id)
    {
        ExtModelFieldRef extModelFieldRef = extModelFieldRefMapper.selectExtModelFieldRefById(id);
        ExtModelField extModelField = extModelFieldService.selectExtModelFieldById(extModelFieldRef.getExtModelFieldId());
        if(extModelField== null)
            throw new ServiceException("无效引用字段!");
        int row =  extModelFieldRefMapper.deleteExtModelFieldRefById(id);
        //检查信息范围必须为全局
        if(!IBusinessConstant.SCOPE_GLOBAL.equals(extModelField.getScope()))
            throw new ServiceException("引用字段必须为全局的！");
        //切换数据源
        SqlSession sqlSession = null;
        //修改原表，删除字段
        try {
            String key = dataSourceService.getKey(SecurityUtils.getEnterpriseCode(),SecurityUtils.getApplicationCode(),extModelFieldRef.getDatasourceName());
            sqlSession = dataSourceService.switchDataSource(key);
            extModelField.setEnName(extModelFieldRef.getEnName());
            extModelDefInstanceMapper = sqlSession.getMapper(ExtModelDefInstanceMapper.class);
            extModelDefInstanceMapper.dropField(extModelFieldRef.getEnName(),extModelField.getFieldEnName());
        }finally {
            if(sqlSession!=null){
                sqlSession.close();
            }
        }
        return row;
    }

    /**
     * 使用表英文名删除字段引用
     *
     * @param extModelDef 表英文名
     * @return 返回删除记录数
     */
    @Override
    public int deleteByTableName(ExtModelDef extModelDef) {
        return extModelFieldRefMapper.deleteByTableName(extModelDef);
    }
}
